package com.tqyan.service.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tqyan.dal.mapper.ChatContentMapper;
import com.tqyan.dal.mapper.ChatMapper;
import com.tqyan.dal.mapper.ChatSettingMapper;
import com.tqyan.dal.mapper.UserSettingMapper;
import com.tqyan.model.controller.response.ChatContentResp;
import com.tqyan.model.dto.*;
import com.tqyan.model.enums.*;
import com.tqyan.model.exp.DefaultException;
import com.tqyan.model.mapping.ChatAssembler;
import com.tqyan.service.service.ChatService;
import com.tqyan.service.service.UserService;
import com.tqyan.util.DisableWordUtil;
import com.tqyan.util.SnowflakeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 会话服务
 * <p> <功能详细描述> </p>
 *
 * @author 陈晨
 * @version 1.0
 * @date 2023/4/12
 */
@Service
@Slf4j
public class ChatServiceImpl implements ChatService {

    @Autowired
    private UserSettingMapper userSettingMapper;
    @Autowired
    private ChatMapper chatMapper;
    @Autowired
    private ChatContentMapper chatContentMapper;
    @Autowired
    private ChatSettingMapper chatSettingMapper;

    @Autowired
    private ChatAssembler chatAssembler;
    @Autowired
    private UserService userService;

    @Override
    public List<ChatDTO> getChatList(String openId) {
        UserDTO user = userService.getUserInfo(openId);
        return chatMapper.queryListByChat(user.getId());
    }

    @Override
    public void delete(String openId, long chatId) {
        UserDTO user = userService.getUserInfo(openId);
        ChatDTO chat = chatMapper.queryById(user.getId(), chatId);
        if (null == chat) {
            return;
        }
        if (ChatTypeEnum.CHAT.getValue() != chat.getType()) {
            throw new DefaultException("仅能删除聊天");
        }
        chatMapper.delete(user.getId(), chat.getId());
    }

    @Override
    public List<ChatContentResp> getChatContentList(String openId, long chatId) {
        UserDTO user = userService.getUserInfo(openId);
        return this.handleContent(user.getId(), chatContentMapper.queryByChat(user.getId(), chatId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ChatContentResp> getChatContentListByDraw(String openId) {
        UserDTO user = userService.getUserInfo(openId);
        ChatDTO chat = chatMapper.queryByDraw(user.getId());
        if (null == chat) {
            chat = this.createChat(user, "绘画", ChatTypeEnum.DRAW);
        }
        return this.handleContent(user.getId(), chatContentMapper.queryByChat(user.getId(), chat.getId()));
    }

    @Override
    public ChatContentResp getChatContent(String openId, long chatId, long chatContentId) {
        UserDTO user = userService.getUserInfo(openId);
        ChatContentDTO chatContent = chatContentMapper.queryById(user.getId(), chatId, chatContentId);
        if (null == chatContent) {
//            log.error("[聊天] userId={}, chatId={}, chatContentId={}, 查询内容为空"
//                    , user.getId(), chatId, chatContentId);
            ChatContentResp resp = new ChatContentResp();
            resp.setUserId(user.getId() + "");
            resp.setChatId(chatId + "");
            resp.setChatContentId(chatContentId + "");
            resp.setContent("");
            resp.setType(ChatTypeEnum.CHAT.getValue());
            resp.setStatus(ChatContentStatusEnum.INCOMPLETE.getValue());
            return resp;
        }
        if (null != chatContent.getQuestionId()) {
            chatContent = chatContentMapper.queryByQuestionId(user.getId(), chatId, chatContent.getQuestionId());
        }
        return this.handleContent(user.getId(), chatContent);
    }

    @Override
    public ChatContentResp handleContent(long userId, ChatContentDTO content) {
        if (null == content) {
            throw new DefaultException("会话内容不存在");
        }
        // 未完成
        if (ChatContentStatusEnum.INCOMPLETE.getValue() == content.getStatus()) {
            int rnd = (int) (Math.random() * 4) + 2;
            String waiting = StringUtils.leftPad("", rnd, ".");
            content.setContent(content.getContent() + waiting);
            return chatAssembler.convertChatContent(content);
        }
        // 已完成
        boolean isPicture = false;
        if (ChatContentStatusEnum.COMPLETED.getValue() == content.getStatus()) {
            // GPT图片绘制完成, 添加图片地址
            if (content.getUserId() == 0 && ChatContentTypeEnum.PICTURE.getValue() == content.getType()) {
                // 查询问题
                String questionContent = "";
                if (null != content.getQuestionId()) {
                    ChatContentDTO question = chatContentMapper.queryById(
                            userId, content.getChatId(), content.getQuestionId());
                    if (null != question) {
                        questionContent = question.getContent();
                    }
                }
                JSONObject json = new JSONObject();
                json.put("question", questionContent);
                json.put("original", IMAGE_PATH + content.getContent());
                json.put("thumbnail", IMAGE_PATH_THUMBNAIL + content.getContent());
                content.setContent(json.toString());
                isPicture = true;
            }
        }
        // 过滤禁用词
        content.setContent(DisableWordUtil.filter(content.getContent()));

        // convert
        ChatContentResp resp = chatAssembler.convertChatContent(content);
        if (!isPicture) {
            this.handleContent(resp);
        }
        return resp;
    }

    @Override
    public void handleContent(ChatContentResp resp) {
        try {
            JSONObject contentJSON = JSONObject.parseObject(resp.getContent());
            // 文本内容
            resp.setContent((String) contentJSON.get("content"));
            // 文件
            resp.setFileName((String) contentJSON.get("fileName"));
            resp.setFileUrl((String) contentJSON.get("fileUrl"));
            resp.setFileSize((String) contentJSON.get("fileSize"));
            resp.setFileType((String) contentJSON.get("fileType"));
            resp.setFileType((String) contentJSON.get("fileType"));
            // 按钮
            if (null != contentJSON.get("buttons")) {
                JSONArray buttons = contentJSON.getJSONArray("buttons");
                resp.setButtons(new JSONArray());
                for (Object button : buttons) {
                    resp.getButtons().add(JSONObject.parse((String) button));
                }
            }
        } catch (Exception e) {
//            log.error("[内容处理] resp={}, 异常: {}", resp, e.getMessage(), e);
        }
    }

    /**
     * @description 处理会话内容集合
     * <p> <功能详细描述> </p>
     *
     * @author 陈晨
     * @date 2023/4/14 18:25
     */
    private List<ChatContentResp> handleContent(long userId, List<ChatContentDTO> contentList) {
        if (CollectionUtils.isEmpty(contentList)) {
            return Collections.emptyList();
        }
        List<ChatContentResp> respList = new ArrayList<>();
        for (ChatContentDTO content : contentList) {
            respList.add(this.handleContent(userId, content));
        }
        return respList;
    }

    @Override
    public ChatDTO createChat(UserDTO user, String chatName, ChatTypeEnum type) {
        // 会话标题最长20个字符
        if (chatName.length() > 20) {
            chatName = chatName.substring(0, 17) + "...";
        }
        // 创建会话
        ChatDTO chat = new ChatDTO();
        chat.setId(SnowflakeUtils.nextId());
        chat.setUserId(user.getId());
        chat.setChatName(chatName);
        chat.setType(type.getValue());
        if (chatMapper.save(chat) <= 0) {
            throw new DefaultException(String.format("创建会话[%s]失败", chatName));
        }
        // 创建会话设置
        UserSettingDTO userSetting = userSettingMapper.queryByUser(user.getId());
        if (null == userSetting) {
            throw new DefaultException(String.format("创建会话[%s]失败, 用户设置信息不存在", chatName));
        }
        ChatSettingDTO chatSetting = new ChatSettingDTO();
        chatSetting.setUserId(user.getId());
        chatSetting.setChatId(chat.getId());
        chatSetting.setModel(userSetting.getModel());
        chatSetting.setCreativeAbility(userSetting.getCreativeAbility());
        chatSetting.setOpenAiKey(userSetting.getOpenAiKey());
        if (chatSettingMapper.save(List.of(chatSetting)) <= 0) {
            throw new DefaultException(String.format("创建会话[%s]失败, 创建会话设置失败", chatName));
        }
        return chat;
    }

    @Override
    public ChatSettingDTO getChatSetting(String openId, long chatId) {
        UserDTO user = userService.getUserInfo(openId);
        return chatSettingMapper.queryByChat(user.getId(), chatId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setModel(String openId, long chatId, int model) {
        ChatModelEnum modelEnum = ChatModelEnum.get(model);
        if (null == modelEnum) {
            throw new DefaultException("会话模式错误");
        }
        UserDTO user = userService.getUserInfo(openId);
        ChatSettingDTO chatSetting = new ChatSettingDTO();
        chatSetting.setUserId(user.getId());
        chatSetting.setChatId(chatId);
        chatSetting.setModel(model);
        boolean result = chatSettingMapper.update(chatSetting) > 0;
        log.info("[会话设置] openId={}, chatId={}, model={}, 会话模式, 设置【{}】"
                , openId, chatId, model, result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setCreativeAbility(String openId, long chatId, int creativeAbility) {
        ChatCreativeAbilityEnum creativeAbilityEnum = ChatCreativeAbilityEnum.get(creativeAbility);
        if (null == creativeAbilityEnum) {
            throw new DefaultException("创造力错误");
        }
        UserDTO user = userService.getUserInfo(openId);
        ChatSettingDTO chatSetting = new ChatSettingDTO();
        chatSetting.setUserId(user.getId());
        chatSetting.setChatId(chatId);
        chatSetting.setCreativeAbility(creativeAbility);
        boolean result = chatSettingMapper.update(chatSetting) > 0;
        log.info("[会话设置] openId={}, chatId={}, creativeAbility={}, 创造力, 设置【{}】"
                , openId, chatId, creativeAbility, result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setOpenAiKey(String openId, long chatId, String openAiKey) {
        UserDTO user = userService.getUserInfo(openId);
        ChatSettingDTO chatSetting = new ChatSettingDTO();
        chatSetting.setUserId(user.getId());
        chatSetting.setChatId(chatId);
        chatSetting.setOpenAiKey(openAiKey);
        boolean result = chatSettingMapper.update(chatSetting) > 0;
        log.info("[会话设置] openId={}, chatId={}, openAiKey={}, 设置【{}】"
                , openId, chatId, openAiKey, result);
        return result;
    }

    public static void main(String[] args) {
        String service = "https://dev.tqyan.com/paper/download/";
        String uri = "李白大战孙悟空_fc1879a41e2a430bb9468f2f0652e153.docx";
        String encode = URLEncoder.encode(uri, StandardCharsets.UTF_8);
        System.out.println(service + encode);
    }

}


